﻿#ifndef AaCore_H
#define AaCore_H

#include "systemCore/worker.h"
#include "AxisModule/singleaxis.h"
#include "AxisModule/xyzmodule.h"
#include "CompositeElement/sccylinder.h"
#include "CompositeElement/scvacuum.h"
#include "CompositeElement/twoaxisplanner.h"
#include "Tray/trayconfig.h"
#include "TwoDimCali/twodimensioncalibration.h"
#include "VisionManager/visionmanager.h"
#include "namedefinition.h"
#include "systemCore/worker.h"
#include "uphhelper.h"
#include "aacoreconfig.h"

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

#include "visionavadaptor.h"
#include "sfr.h"
#include "imageprovider.h"

#include "namedefinition.h"
#include "aadata.h"
#include "sfrworker.h"
#include "utils.h"
#include "../DriverRepos/Graber/xfgraber.h"
#include "displaythread.h"

#define AA_PIECE_START "Start"
#define AA_PIECE_LOAD_CAMERA "Load Camera"
#define AA_PIECE_INIT_LENS "Init_Lens"
#define AA_PIECE_INIT_CAMERA "Init Camera"
#define AA_PIECE_PR_TO_BOND "PR To Bond"
#define AA_PIECE_INITIAL_TILT "Initial Tilt"
#define AA_PIECE_PICK_LENS "AA Pick Lens"
#define AA_PIECE_LOAD_MATERIAL "Load Material"
#define AA_PIECE_UNLOAD_LENS "AA Unload Lens"
#define AA_PIECE_Z_OFFSET "Z Offset"
#define AA_PIECE_XY_OFFSET "XY Offset"
#define AA_PIECE_AA "AA"
#define AA_PIECE_OC "OC"
#define AA_PIECE_MTF "MTF"
#define AA_PIECE_UV "UV"
#define AA_PIECE_DISPENSE "Dispense"
#define AA_PIECE_Y_LEVEL "Y_Level"
#define AA_PIECE_OTP "OTP"
#define AA_PIECE_DELAY "Delay"
#define AA_PIECE_JOIN "Join"
#define AA_PIECE_SAVE_IMAGE "Save Image"
#define AA_PIECE_ACCEPT "Accept"
#define AA_PIECE_REJECT "Reject"
#define AA_PIECE_TERMINATE "Terminate"
#define AA_PIECE_GRR "GRR"
#define AA_PIECE_PARTICAL_CHECK "Partical Check"

#define AA_PIECE_INITIAL_POSITION "Init Pos"
#define AA_PIECE_INIT_SENSOR "Init Sensor"
#define AA_LOAD_CAMERA "Load Camera"
#define AA_PR_TO_BOND "PR2Bond"
#define AA_DISPENSE  "Disp"
#define AA_UV        "UV"
#define AA_UNLOAD_CAMERA "Unload Camera"
#define AA_DELAY     "DELAY"
#define AA_PIECE_END "END"

SILICOOL_DECLARE_LOGGING_CATEGORY(aaCoreTimeLog, )

class AaHead;

struct AAResultStruct
{
public:
    AAResultStruct() {
        sensorState = AAResult::RawSensor;
        lensState = AAResult::RawLens;
        productState = AAResult::NoProduct;
    }
public:
    QString sensorState;
    QString lensState;
    QString productState;
};

class AACore : public Worker
{
    Q_OBJECT
    Q_PROPERTY(bool liveImageDisplayStatus READ liveImageDisplayStatus WRITE setLiveImageDisplayStatus NOTIFY paramsChanged)

public:
    AACore();
    ~AACore() override;

    AACoreConfig *getAACoreConfig() const
    {
        return aaCoreConfig;
    }

    //Worker interface
protected:
    virtual void initEventHandle() override;
    virtual void startEventHandle(const WorkerEvent &event) override;
    virtual void stopEventHandle() override {}
    virtual void allWorkerStopped() override;
    virtual void purgeEventHandle() override;
    virtual void resetEventHandle() override;
    virtual void homeWorker(bool moveToReadyPosAfterHome) override;

public:
    Q_INVOKABLE void test();
    Q_INVOKABLE void loadFlowchart(QString json);
    Q_INVOKABLE void runFlowchart();
    void setAAHead(AaHead *aaHead);
    AAResultStruct getAAResultCurrentUnit();
    ImageProvider * liveImageProvider;
    ImageProvider * mtfImageProvider;
    ImageProvider * ocImageProvider;
    ImageProvider * aaDebugImageProvider;
    AAData aaData_1;  // For Display Channel 1
    AAData aaData_2;  // For Display Channel 2
    AAData mtfLoopTestData; //For MTF Loop Test
    //自动运行逻辑
    bool liveImageDisplayStatus() const
    {
        return m_liveImageDisplayStatus;
    }

public slots:
    //AA Material State Related
    void resetAAResultCurrentUnitToRaw();
    void setNgSensor();
    void setNgLens();
    void setNgProduct();
    void setGoodProduct();
    //
    void runAAFlowchart();
    void storeSfrResults(unsigned int index, vector<Sfr_entry> sfrs, int timeElasped);
    //手动调试逻辑
    void performManualTest(QString operatorId, QString paramsJson);
    void performInitCameraMaunal();
    void performOCManual();
    void performMTFLoopTest();
    void performClearMTFLoopTestResult();
    void performStopMTFLoopTest();
    void performMTFManual();
    void performAADebugImage();
    void performOCCalibration();
    void performGrabImage();
    void performCloseCamera();
    void performAATest();
    void performAATiltCalibration();
    void performFOVCalibration();
    void drawBmp24(QImage);
    void displayThreadExit();

    void setLiveImageDisplayStatus(bool liveImageDisplayStatus)
    {
        if (m_liveImageDisplayStatus == liveImageDisplayStatus)
            return;

        m_liveImageDisplayStatus = liveImageDisplayStatus;
        emit paramsChanged(m_liveImageDisplayStatus);
    }

signals:
    void displayAAImageInUI(QString type);

    void paramsChanged(bool liveImageDisplayStatus);

private:

    XFGraber *xfGrabber = Q_NULLPTR;

    XYZModule *sUTXYZ = Q_NULLPTR;
    XYZModule *aaThetaXYZ = Q_NULLPTR;

    AaHead *aaHead = Q_NULLPTR;

    AACoreConfig *aaCoreConfig;
    ConfigFile *aaCoreConfigFile;

    SfrWorkerController *sfrWorkerController;

    AAResultStruct currentAAResult;

    QVector<AA_Helper::patternAttr> pattern_v;

    QJsonDocument currentFlowchartDocument;

    bool isAaHeadStopped = false;

    int currentChartDisplayChannel = 0;

    bool isMTFLoopTestRunning = false;

    QVariantMap last_aa_result;

    bool performTest(QString testItemName, QJsonValue properties);

    std::unordered_map<unsigned int, std::vector<Sfr_entry>> clustered_sfr_map;

    QVariantMap sfrFitCurve_Advance(int resize_factor, double start_pos);
    threeDPoint aaCorePlaneFitting(std::vector<threeDPoint> points);
    double calculateDFOV(cv::Mat img);

//Image thread
    QThread *m_pDisplayThread = nullptr;
    DisplayThread *m_pObjdisplayThread = nullptr;
    void beginThread();
    void endThread();
    bool isDisplayThreadOn = false;
//AA Core Test item
    bool performInitCamera(QJsonValue params);
    bool performOC(QJsonValue params);
    bool performMTF(QJsonValue params);
    bool performAA(QJsonValue params);
    bool performDelay(QJsonValue params);
    bool performAAOffline(QJsonValue params);
    bool performDispense(QJsonValue params);
    bool performZOffset(QJsonValue params);
    bool performUV(QJsonValue params);

//Image Tools
    static QImage cvMat2QImage(const cv::Mat& img);
    bool m_liveImageDisplayStatus = false;
};

#endif // AaHead_H
